#include "httpclient.h"
#include "api/apiinfo.h"
#include "curl/curl.h"

// 静态初始化curl
static struct CurlInitializer
{
	CurlInitializer()
	{
		// 初始化curl
		curl_global_init(CURL_GLOBAL_DEFAULT);
	}

	~CurlInitializer()
	{
		// 清理curl
		curl_global_cleanup();
	}
} curlInitializer;

// 全局curl初始化器，确保在程序生命周期内只初始化和清理一次
//static CurlInitializer curlInitializer;

HttpClient::HttpClient(std::string url)
	: m_url(std::move(url)), m_httpCode(0)
{
}
HttpClient::~HttpClient() = default;
void HttpClient::setHeader(const std::string& name, const std::string& value)
{
	m_headers[name] = value;
}
long HttpClient::httpCode() const
{
	return m_httpCode;
}
std::string HttpClient::error() const
{
	return m_error;
}
bool HttpClient::post(const std::string& requestData, std::string& responseData)
{
	m_error.clear();
	responseData.clear();

	if (m_url.empty())
	{
		m_error = "未指定请求HTTP(S)地址。";
		return false;
	}

	// 创建curl句柄
	CURL* curl = curl_easy_init();
	if (!curl)
	{
		m_error = "创建curl句柄失败。";
		return false;
	}

	// 设置URL
	curl_easy_setopt(curl, CURLOPT_URL, m_url.c_str());

	if (!requestData.empty())
	{
		// 设置POST数据
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestData.c_str());
		curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, requestData.length());
	}
	else
	{
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
	}

	// 设置写数据回调函数
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);

	// 设置请求头
	struct curl_slist* headers = nullptr;
	// 如果没有设置Content-Type，默认设置为application/json
	// bool hasContentType = false;
	for (const auto& [key, value]: m_headers)
	{
		// if (header.first == "Content-Type") {
		// 	hasContentType = true;
		// }
		//std::string headerStr = key + ":" + value;
		std::string headerStr = key;
		headerStr.append(":");
		headerStr.append(value);
		headers = curl_slist_append(headers, headerStr.c_str());
	}
	// if (!hasContentType) {
	// 	headers = curl_slist_append(headers, "Content-Type: application/json");
	// }
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

	// 设置超时时间(毫秒)
	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, ApiInfo::connectTimeout());//连接超时时长
	curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, ApiInfo::requestTimeout());       //总超时时长

	//在屏幕打印请求连接过程和返回http数据
	//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

	// 执行请求
	const CURLcode res = curl_easy_perform(curl);

	// 获取HTTP状态码
	curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &m_httpCode);

	// 检查结果
	if (res != CURLE_OK)
	{
		m_error = "执行curl_easy_perform()失败: " + std::string(curl_easy_strerror(res));
	}

	// 清理
	curl_slist_free_all(headers);
	curl_easy_cleanup(curl);

	return res == CURLE_OK;
}
size_t HttpClient::writeCallback(void* ptr, const size_t size, const size_t nMemb, std::string* userData)
{
	const size_t totalSize = size * nMemb;
	userData->append(static_cast<char*>(ptr), totalSize);
	return totalSize;
}